package proxy.jdk2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * 日志横切逻辑
 */
public class LogHandler implements InvocationHandler {

    private Object target;

    public LogHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        System.out.println(method.getName()+"方法开始执行，入参："+ Arrays.asList(args));
        Object result = null;
        try {
            result = method.invoke(target, args);
            System.out.println(method.getName()+"方法执行结果："+result);
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
           throw new RuntimeException(method.getName()+"方法出现异常："+throwable.getMessage());
        }finally {
            System.out.println(method.getName()+"方法执行结束");
        }
    }

    /**
     * 根据被代理对象，创建代理对象
     * @param target 被代理对象
     * @return 代理对象
     * 原理：使用和target同样的类加载器加载代理对象，代理对象是根据target实现的接口来创建的，
     * 代理对象也实现了接口方法，每个实现的方法内部都去调用InvocationHandler#invoke()方法，
     * invoke()方法实现在调用业务逻辑前去进行一些增强处理。
     */
    public static Object getProxy(Object target){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new LogHandler(target));
    }

}
